---
title: Customization - Mitosis
---

# Customization

When building Mitosis components, you might sometimes have unique and special needs. If you want to transform your Mitosis-generated output to fit your needs, by doing things like:

- add a special import statement at the top of each mitosis file
- remove a specific style attribute for one given target (for example, if you want your `react-native` output to omit a specific styling attribute that you rley on elsewhere.)
- modify only _some_ of your components to be dynamically imported

This (and much more) is possible thanks to Mitosis' powerful plugin system.

## Plugins

In your directory's `mitosis.config.js`, you can provide a `plugins` array for each code generator. You have many different kinds of plugins:

```tsx
export type Plugin = {
  name?: stirng;
  order?: number; // Sort plugins by number, no matter the position of the array
  build?: {
    // Happens before build
    pre?: (targetContext: TargetContext) => void | Promise<void>;
    // Happens after build
    post?: (
      targetContext: TargetContext,
      files?: {
        componentFiles: OutputFiles[];
        nonComponentFiles: OutputFiles[];
      },
    ) => void | Promise<void>;
  };
  json?: {
    // Happens before any modifiers
    pre?: (json: MitosisComponent) => MitosisComponent | void;
    // Happens after built in modifiers
    post?: (json: MitosisComponent) => MitosisComponent | void;
  };
  code?: {
    // Happens before formatting
    pre?: (code: string, json: MitosisComponent) => string;
    // Happens after formatting
    post?: (code: string, json: MitosisComponent) => string;
  };
};
```

We run plugins at 4 different points:

- preJSON: before any default modifiers run on the Mitosis JSON
- postJSON: after all built-in modifiers run on the Mitosis JSON
- preCode: before any formatting runs on the Mitosis output (we format using `prettier`)
- postCode: after any formatting runs on the Mitosis output (we format using `prettier`)

The JSON plugins receive the Mitosis component's full JSON object as an argument. Similarly, the code plugins receive the code string.

We even use plugins internally to generate Mitosis components! Here's an example of our [react-native plugin](https://github.com/BuilderIO/mitosis/blob/328572740bb3ff2f66924d431dc6360f5f4e0c62/packages/core/src/generators/react-native.ts#L82-L118).

You will see that we traverse the JSON nodes, and for each MitosisNode, we remove `class` and `className` values and bindings. That's because React-Native does not support class-names on mobile.

## useMetadata

What happens if you want a plugin to only apply to a specific set of components?
Or if you'd like to provide some metadata for your plugin,
and that metadata will depend on which component is being compiled?

This is where our `useMetadata` hook comes in handy.
All you need to do is import and use the hook
(you can use it anywhere in your mitosis component file, even at the top root level!):

```tsx
import { useMetadata } from '@builder.io/mitosis';

useMetadata({ mySpecialComponentType: 'ABC' });

export default function SmileReviews(props: SmileReviewsProps) {
  return <div>{/**/}</div>;
}
```

The metadata will be stored in your mitosis component's JSON
, under `json.meta.useMetadata.mySpecialComponentType`.
You can then use it in your JSON pre/post plugins:

```tsx
const plugin = {
  json: {
    pre: (json: MitosisComponent) => {
      const myComponentType = json.meta.useMetadata?.mySpecialComponentType;
      if (myComponentType === 'ABC') {
        //...
      }
    },
  },
};
```

Check the [example](https://github.com/BuilderIO/mitosis/tree/main/examples/metadata/src/components/metadata.lite.tsx) to see a complex `useMetadata` usage.

## Component JSON

The way Mitosis' engine works is:

- you write a `.lite.jsx` or `.lite.tsx` component
- the mitosis JSX parser converts it to a `MitosisComponent` JSON
- that JSON is fed to the generator(s) of your choice, which provide it to the plugins.

For more information on what the JSON contains, check out the documented types:

- [MitosisComponent](https://github.com/BuilderIO/mitosis/blob/main/packages/core/src/types/mitosis-component.ts)
- [MitosisNode](https://github.com/BuilderIO/mitosis/blob/main/packages/core/src/types/mitosis-node.ts): Each `MitosisComponent` will have multiple `MitosisNode` under `component.children`. Each node represents a DOM/JSX node


## Example

This is an example what you could do with a plugin.
In this example we want to create a documentation for one of our components, based on the target.

The example component `button.docs.lite.tsx`:

````tsx
/* button.docs.lite.tsx */
import { useMetadata } from '@builder.io/mitosis';
import MyButton from './my-button.lite';

useMetadata({
  docs: {
    name: "This is the name of my button"
  },
});

export default function ButtonDocs(props: any) {
  return <MyButton name={props.name}></MyButton>;
}
````

The mitosis config `mitosis.config.cjs`:

````js
/**
 * @type {import('@builder.io/mitosis'.MitosisConfig)}
 */
module.exports = {
  files: 'src/**',
  targets: [
    'angular',
    'react',
    'vue'
  ],
  commonOptions: {
    typescript: true,
    explicitBuildFileExtensions: {
      '.md': /.*(docs\.lite\.tsx)$/g
    },
    plugins: [
      () => ({
        code: {
          post: (code, json) => {
            if (json.meta?.useMetadata?.docs) {
              return (
                `# ${json.name} - ${json.pluginData?.target}\n\n` +
                `${JSON.stringify(json.meta?.useMetadata?.docs)}\n\n` +
                'This is the content:\n' +
                '````\n' +
                code +
                '\n````'
              );
            }

            return code;
          }
        }
      })
    ]
  }
};
````

We generate a new `button.docs.md` with a content based on the target, e.g. `vue`:

````markdown
# ButtonDocs - vue

{"name":"This is the name of my button"}

This is the content:
\````
<template>
  <MyButton :name="name"></MyButton>
</template>

<script setup lang="ts">
  import MyButton from "./my-button.vue";

  const props = defineProps(["name"]);
</script>

\````
````

> **Note:** We use `commonOptions` here to apply the plugin to every target.
>
> We use `explicitBuildFileExtensions` to transform the file extension always to `.md`,
otherwise you would get the default extension for your target. Like `.vue` for vue or `.tsx` for react.